/*
 * SVMClass.cpp
 *
 *  Created on: Dec 23, 2013
 *      Author: thanhkm
 */

#include "Learning.h"

Learning::Learning() {

}

Learning::~Learning() {
}

void Learning::train(cv::Mat& trainingData, cv::Mat& trainingClasses) {
	// Set up SVM's parameters
	CvSVMParams params;
	params.svm_type = CvSVM::C_SVC;
	params.kernel_type = CvSVM::RBF;
	params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);

	// SVM training
	svm.train(trainingData, trainingClasses, cv::Mat(), cv::Mat(), params);
}

void Learning::predict(cv::Mat& testData, cv::Mat& reponses){
	reponses = cv::Mat(testData.rows, 1, CV_32F);
	for(int i = 0; i < testData.rows; i++) {
			cv::Mat sample = testData.row(i);
			reponses.at<float>(i, 0) = svm.predict(sample);
	}
}

void Learning::convertToMat(std::vector<int> vecLabels, cv::Mat &matLabels){
	int numberOfLabels = vecLabels.size();
	matLabels = cv::Mat(numberOfLabels, 1, CV_32FC1);
	for(int i = 0; i < numberOfLabels; i++){
		matLabels.at<float>(i,0) = vecLabels[i];
	}
}

// accuracy
void Learning::evaluate2(cv::Mat& predicted, cv::Mat& actual) {
	assert(predicted.rows == actual.rows);
	cv::Mat matrix_confusion = cv::Mat::zeros(13, 13, CV_32SC1);
	for (int i = 1; i < 13; i++){
		for (int j = 1; j < 13; j++){
			matrix_confusion.at<float>(i,j) = 0;
		}
	}

	int total_predicted = 0;
	int total_true = 0;
	int total_false = 0;

	for(int i = 0; i < actual.rows; i++) {
		int p = (int)predicted.at<float>(i,0);
		int a = (int)actual.at<float>(i,0);
		// predict in column and actual in row
		matrix_confusion.at<float>(a,p)++;
		total_predicted++;
		if (a == p){
			total_true++;
		} else {
			total_false++;
		}
	}
	std::cout << matrix_confusion << std::endl;
	std::cout << "total true: " << total_true << std::endl;
	std::cout << "total predict: " << total_predicted << std::endl;
	std::cout << "true rate: " << (1.0 * total_true) / (total_predicted) << std::endl;
}

// accuracy
void Learning::evaluate(cv::Mat& predicted, cv::Mat& actual) {
	assert(predicted.rows == actual.rows);
	int matrix_confusion[13][13];
	for (int i = 0; i < 13; i++){
		for (int j = 0; j < 13; j++){
			matrix_confusion[i][j] = 0;
		}
	}

	int total_predicted = 0;
	int total_true = 0;
	int total_false = 0;

	for(int i = 0; i < actual.rows; i++) {
		int p = (int)predicted.at<float>(i,0);
		int a = (int)actual.at<float>(i,0);
		// predict in column and actual in row
		matrix_confusion[a][p]++;
		total_predicted++;
		if (a == p){
			total_true++;
		} else {
			total_false++;
		}
	}

	for (int i = 0; i < 13; i++){
		for (int j = 0; j < 13; j++){
			std::cout << matrix_confusion[i][j] << " & ";
		}
		std::cout << " \\\\ \\hline" << std::endl;
	}

	std::cout << "total true: " << total_true << std::endl;
	std::cout << "total predict: " << total_predicted << std::endl;
	std::cout << "true rate: " << (1.0 * total_true) / (total_predicted) << std::endl;
}
